package com.soft.zosagent.server;

import com.soft.zosagent.common.MarshallingCodeCFactory;
import com.soft.zosagent.zoscls.MvsCommandUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;

/**
 * zos agent program
 */
public class ZosAgent {
    public static void main(String[] args) throws Exception {
        System.out.println("ZosAgent");
        int port = 9999;
        String portstr="";
        CommandLineParser parser = new BasicParser();
        Options options = new Options();
        options.addOption("p", "port", true, "file service port.");
        options.addOption("loglvl", "loglvl", true, "log level.");
        options.addOption("ipfilter", null, true, "ip filter rules.");
        options.addOption("ssl",null,false,"ssl enable");
        CommandLine commandLine = parser.parse(options, args);//解析参数
        if (commandLine.hasOption("p")) {//判断参数是否存在
            portstr = commandLine.getOptionValue("p");//返回参数的字符串值
        }

        if (portstr != null && portstr.length() > 0) {
            try {
                port = Integer.valueOf(portstr);
            } catch (NumberFormatException e) {
            }
        }
        ZosAgent zosAgent = new ZosAgent();
        zosAgent.bind(port);
    }

    public void bind(int port) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {

            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)

                    .handler(new LoggingHandler(io.netty.handler.logging.LogLevel.ERROR))
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch)
                                throws Exception {
                            //System.out.println("init socket channel pipline.");
                            ch.pipeline().addLast("marEncoder", MarshallingCodeCFactory.buildMarshallingEncoder());
                            ch.pipeline().addLast("marDecoder",
                                    MarshallingCodeCFactory
                                            .buildMarshallingDecoder());
                            //ch.pipeline().addLast("chunkedWriteHandler",new ChunkedWriteHandler());
                            //String uniqueId = UUID.randomUUID().toString();
                            ch.pipeline().addLast("ServerHandler",new ServerHandler());

                        }
                    });


            ChannelFuture f = b.bind(port).sync();

            //System.out.println(JSON.toJSONString(f.channel().pipeline().names()));

            //f.channel().closeFuture().sync();
            System.out.println("arch:"+System.getProperty("os.arch"));
            System.out.println("name:"+System.getProperty("os.name"));
            if(System.getProperty("os.arch").contains("s390") || System.getProperty("os.name").contains("z/OS")) {
                MvsCommandUtil.WaitConsoleCmd();
                f.channel().close().sync();
            }else {
                f.channel().closeFuture().sync();
            }

        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
